[Amazon SageMaker] 組み込みアルゴリズム(ImageClassification)で作成したモデルをOpenVINOツールキットで使用してみました
1 はじめに
CX事業本部の平内(SIN)です。
OpenVINO ツールキットでは、モデルをIRと呼ばれる中間表現フォーマットにして利用します。そして、同ツールキットには、各種のフレームワークで作成したモデルを、IRに変換するツールが含まれています。
今回は、Amazon SageMaker(以下、SageMaker)の組み込みアルゴリズム(画像分類)で作成したモデルを変換して使用してみました。
IRは、以下の3種類が生成可能ですが、今回の試した作業は、FP16及びFP32となっています。
- FP16 16ビット浮動小数点演算 (NCS)
- FP32 32ビット浮動小数点演算 (CPU)
- INT8 8ビット整数演算
2 モデル
変換に使用したモデルは、下記で作成したものです。
出力先に格納されている、model.tar.gzを解凍すると、3つのファイルが格納されています。
こちらは、MXNet形式のモデルです。
3 Model Optimizer
Model Optimizerは、OpenVINOツールキットをインストールする手順の中で展開されるようになっています。
参考:Model Optimizer Developer Guide
変換作業は、Model Optimizerがインストールされてたディレクトリで、mo_mxnet.py(MXNet用)を実行するだけです。
最初に、FP16用とFP32用を作成するためディレクトリを作成しておきます。
以下は、FP16で作成している例です。
$ cd /opt/intel/openvino/deployment_tools/model_optimizer $ export WORK_DIR=/tmp/model $ export FP_TYPE=FP16 $ python3 mo_mxnet.py --input_model $WORK_DIR/image-classification-0012.params --input_shape \[1,3,224,224\] --output_dir $WORK_DIR/$FP_TYPE --data_type $FP_TYPE Model Optimizer arguments: Common parameters: - Path to the Input Model: /tmp/model/image-classification-0012.params - Path for generated IR: /tmp/model/FP16 - IR output name: image-classification-0012 - Log level: ERROR - Batch: Not specified, inherited from the model - Input layers: Not specified, inherited from the model - Output layers: Not specified, inherited from the model - Input shapes: [1,3,224,224] - Mean values: Not specified - Scale values: Not specified - Scale factor: Not specified - Precision of IR: FP16 - Enable fusing: True - Enable grouped convolutions fusing: True - Move mean values to preprocess section: False - Reverse input channels: False MXNet specific parameters: - Deploy-ready symbol file: None - Enable MXNet loader for models trained with MXNet version lower than 1.0.0: False - Prefix name for args.nd and argx.nd files: None - Pretrained model to be merged with the .nd files: None - Enable saving built parameters file from .nd files: False - Use the config file: None Model Optimizer version: [ SUCCESS ] Generated IR version 10 model. [ SUCCESS ] XML file: /tmp/model/FP16/image-classification-0012.xml [ SUCCESS ] BIN file: /tmp/model/FP16/image-classification-0012.bin [ SUCCESS ] Total execution time: 38.71 seconds. [ SUCCESS ] Memory consumed: 944 MB.
FP32及び、FP16を作成すると、指定した出力先に、.xmlと .bin が作成されます。これが、IRフォーマットのモデルです。
4 コード
以下は、生成したIRを使用して、MacOS上で推論しているコードです。
Syohin40クラスは、商品検出のモデルをラップしたクラスで、カメラから取得した画像を、モデルの入力形式に変換して推論しています。
CPUで実行して、推論にかかった時間は、0.1〜0.3秒程度でした。
index.py
import numpy as np import time import cv2 import time from openvino.inference_engine import IECore from PIL import ImageFont, ImageDraw, Image from model import Model class Syohin40(Model): def __init__(self, ie, device, model): super().__init__(ie, device, model) _, _, h, w = self.input_size self.__input_height = h self.__input_width = w def __prepare_frame(self, frame): initial_h, initial_w = frame.shape[:2] scale_h, scale_w = initial_h / float(self.__input_height), initial_w / float(self.__input_width) in_frame = cv2.resize(frame, (self.__input_width, self.__input_height)) in_frame = in_frame.transpose((2, 0, 1)) in_frame = in_frame.reshape(self.input_size) return in_frame, scale_h, scale_w def infer(self, frame): in_frame, _, _ = self.__prepare_frame(frame) result = super().infer(in_frame) # [1, 41] => [41] return result.squeeze() # MacOS ie = IECore() device = "CPU" syohin40 = Syohin40(ie, device, "image-classification-0012") CLASSES = ["ポリッピー(GREEN)","OREO","カントリーマム","ポリッピー(RED)","柿の種(わさび)" ,"通のとうもろこし","CHEDDER_CHEESE","ピーナッツ","ストーンチョコ","PRETZEL(YELLOW)" ,"海味鮮","柿の種","カラフルチョコ","フルグラ(BROWN)","NOIR" ,"BANANA(BLOWN)","チーズあられ","俺のおやつ","PRIME","CRATZ(RED)" ,"CRATZ(GREEN)","揚一番","ポリッピー(YELLOW)","こつぶっこ","アスパラガス" ,"海苔ピーパック","いちご","梅しそチーズあられ","通のえだ豆","柿の種(梅しそ)" ,"PRETZEL(BLACK)","辛子明太子","CRATZ(ORANGE)","チョコメリゼ","フライドポテト(じゃがバター味)" ,"BANANA(BLUE)","でん六豆","パズル","フルグラ(RED)","PRETZEL(GREEN)" ,"フライドポテト(しお味)",] def putText(image, text, point, size, color): font = ImageFont.truetype("./GenShinGothic-Bold.ttf", size) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = Image.fromarray(image) draw = ImageDraw.Draw(image) draw.text(point, text, color, font) image = np.asarray(image) return cv2.cvtColor(image, cv2.COLOR_RGB2BGR) def main(): # OpenCV WIDTH = 640 HEIGHT = 480 FPS = 24 cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT) cap.set(cv2.CAP_PROP_FPS, FPS) while(True): _, frame = cap.read() start = time.time() # 時間計測 out = syohin40.infer(frame) processing_time = time.time() - start print("processing_time {}sec".format(processing_time)) # 表示 prob = np.max(out) index = np.argmax(out) print("Class: %s, probability: %f" % (CLASSES[index], prob)) if(0.4<prob): text = "{} {}".format(CLASSES[index], prob) frame = putText(frame, text, (20, int(HEIGHT) - 120), 60, (255, 255, 255)) cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() main()
LD_LIBRARY_PATHに設定されているはずなのですが、何故か、IECore() からモデル生成すると、libmyriadPlugin.dylibが読み込めないというエラーとなってしまたので、ctypes.cdll.LoadLibraryで一旦読み込んでいます。
model.py
import ctypes class Model: def __init__(self, ie, device, model): modelPath = "./FP32/{}".format(model) if(device=="MYRIAD"): modelPath = "./FP16/{}".format(model) net = ie.read_network(modelPath + ".xml", modelPath + ".bin") # LD_LIBRARY_PATHは、遠ているはずなのに、なぜか読み込みに失敗するので、一回読み込んでおく ctypes.cdll.LoadLibrary('/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64/libinference_engine_lp_transformations.dylib') ctypes.cdll.LoadLibrary('/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64/libmyriadPlugin.dylib') self.exec_net = ie.load_network(network=net, device_name=device, num_requests=2) self.input_name = next(iter(net.input_info)) self.output_name = next(iter(net.outputs)) self.input_size = net.input_info[self.input_name].input_data.shape self.output_size = net.outputs[self.output_name].shape def infer(self, data): input_data = {self.input_name: data} infer_result = self.exec_net.infer(input_data) return infer_result[self.output_name]
動画は、上記のコードを実行してる様子です。
5 最後に
今回は、SageMakerで作成したモデルをOpenVINOツールキットで利用してみました。
OpenVINOツールキットでは、モデルごとにCPU、GPUを振り分けて使用したり、USBで追加可能なNCSなどがあります。
SageMakerで作成したモデルも問題なく変換して利用可能ということで、一段と、利用範囲が広がるかも知れません。